#include "config.h"
#include "gdk.h"
+#include "gdkscreen-quartz.h"
#include "gdkprivate-quartz.h"
-/* FIXME: If we want to do it properly, this should be stored
- * in a proper GdkScreen subclass.
- */
-static GdkColormap *default_colormap = NULL;
-static int n_screens = 0;
-static GdkRectangle *screen_rects = NULL;
-static guint screen_changed_id = 0;
+static void gdk_screen_quartz_dispose (GObject *object);
+static void gdk_screen_quartz_finalize (GObject *object);
+static void gdk_screen_quartz_calculate_layout (GdkScreenQuartz *screen);
+
+static void display_reconfiguration_callback (CGDirectDisplayID display,
+ CGDisplayChangeSummaryFlags flags,
+ void *userInfo);
+
+G_DEFINE_TYPE (GdkScreenQuartz, _gdk_screen_quartz, GDK_TYPE_SCREEN);
+
+static void
+_gdk_screen_quartz_class_init (GdkScreenQuartzClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gdk_screen_quartz_dispose;
+ object_class->finalize = gdk_screen_quartz_finalize;
+}
+
+static void
+_gdk_screen_quartz_init (GdkScreenQuartz *screen_quartz)
+{
+ GdkScreen *screen = GDK_SCREEN (screen_quartz);
+
+ gdk_screen_set_default_colormap (screen,
+ gdk_screen_get_system_colormap (screen));
+
+ gdk_screen_quartz_calculate_layout (screen_quartz);
+
+ CGDisplayRegisterReconfigurationCallback (display_reconfiguration_callback,
+ screen);
+}
+
+static void
+gdk_screen_quartz_dispose (GObject *object)
+{
+ GdkScreenQuartz *screen = GDK_SCREEN_QUARTZ (object);
+
+ if (screen->default_colormap)
+ {
+ g_object_unref (screen->default_colormap);
+ screen->default_colormap = NULL;
+ }
+ if (screen->screen_changed_id)
+ {
+ g_source_remove (screen->screen_changed_id);
+ screen->screen_changed_id = 0;
+ }
+
+ CGDisplayRemoveReconfigurationCallback (display_reconfiguration_callback,
+ screen);
+
+ G_OBJECT_CLASS (_gdk_screen_quartz_parent_class)->dispose (object);
+}
static void
-screen_rects_init (void)
+gdk_screen_quartz_screen_rects_free (GdkScreenQuartz *screen)
+{
+ screen->n_screens = 0;
+
+ if (screen->screen_rects)
+ {
+ g_free (screen->screen_rects);
+ screen->screen_rects = NULL;
+ }
+}
+
+static void
+gdk_screen_quartz_finalize (GObject *object)
+{
+ GdkScreenQuartz *screen = GDK_SCREEN_QUARTZ (object);
+
+ gdk_screen_quartz_screen_rects_free (screen);
+}
+
+
+static void
+gdk_screen_quartz_calculate_layout (GdkScreenQuartz *screen)
{
NSArray *array;
NSRect largest_rect;
GDK_QUARTZ_ALLOC_POOL;
- array = [NSScreen screens];
+ gdk_screen_quartz_screen_rects_free (screen);
- n_screens = [array count];
- screen_rects = g_new0 (GdkRectangle, n_screens);
+ array = [NSScreen screens];
- /* FIXME: as stated above the get_width() and get_height() functions
- * in this file, we only support horizontal screen layouts for now.
+ /* FIXME: For now we only support screen layouts where the screens are laid
+ * out horizontally. Mac OS X also supports laying out the screens vertically
+ * and the screens having "non-standard" offsets from eachother. In the
+ * future we need a much more sophiscated algorithm to translate these
+ * layouts to GDK coordinate space and GDK screen layout.
*/
+ screen->width = 0;
+ screen->height = 0;
+
+ for (i = 0; i < [array count]; i++)
+ {
+ NSRect rect = [[array objectAtIndex:i] frame];
+
+ screen->width += rect.size.width;
+ screen->height = MAX (screen->height, rect.size.height);
+ }
+
+ screen->n_screens = [array count];
+ screen->screen_rects = g_new0 (GdkRectangle, screen->n_screens);
/* Find the monitor with the largest height. All monitors should be
* offset to this one in the GDK screen space instead of offset to
largest_rect = [[array objectAtIndex:i] frame];
}
- for (i = 0; i < n_screens; i++)
+ for (i = 0; i < screen->n_screens; i++)
{
NSScreen *nsscreen;
NSRect rect;
nsscreen = [array objectAtIndex:i];
rect = [nsscreen frame];
- screen_rects[i].x = rect.origin.x;
- screen_rects[i].width = rect.size.width;
- screen_rects[i].height = rect.size.height;
+ screen->screen_rects[i].x = rect.origin.x;
+ screen->screen_rects[i].width = rect.size.width;
+ screen->screen_rects[i].height = rect.size.height;
if (largest_rect.size.height - rect.size.height == 0)
- screen_rects[i].y = 0;
+ screen->screen_rects[i].y = 0;
else
- screen_rects[i].y = largest_rect.size.height - rect.size.height + largest_rect.origin.y;
+ screen->screen_rects[i].y = largest_rect.size.height - rect.size.height + largest_rect.origin.y;
}
GDK_QUARTZ_RELEASE_POOL;
}
+
static void
-screen_rects_free (void)
+process_display_reconfiguration (GdkScreenQuartz *screen)
{
- n_screens = 0;
+ int width, height;
- g_free (screen_rects);
- screen_rects = NULL;
-}
+ width = gdk_screen_get_width (GDK_SCREEN (screen));
+ height = gdk_screen_get_height (GDK_SCREEN (screen));
+ gdk_screen_quartz_calculate_layout (GDK_SCREEN_QUARTZ (screen));
-static void
-process_display_reconfiguration (void)
-{
- screen_rects_free ();
- screen_rects_init ();
-
- /* FIXME: We should only emit this when the size of screen really
- * has changed. We need to start bookkeeping width, height once
- * we have a proper GdkScreen subclass.
- */
- g_signal_emit_by_name (_gdk_screen, "size-changed");
+ if (width != gdk_screen_get_width (GDK_SCREEN (screen))
+ || height != gdk_screen_get_height (GDK_SCREEN (screen)))
+ g_signal_emit_by_name (_gdk_screen, "size-changed");
}
static gboolean
screen_changed_idle (gpointer data)
{
- process_display_reconfiguration ();
+ GdkScreenQuartz *screen = data;
+
+ process_display_reconfiguration (data);
- screen_changed_id = 0;
+ screen->screen_changed_id = 0;
return FALSE;
}
static void
-screen_changed (CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags,
- void *userInfo)
+display_reconfiguration_callback (CGDirectDisplayID display,
+ CGDisplayChangeSummaryFlags flags,
+ void *userInfo)
{
+ GdkScreenQuartz *screen = userInfo;
+
if (flags & kCGDisplayBeginConfigurationFlag)
{
/* Ignore the begin configuration signal. */
* yet, so we delay our refresh into an idle handler.
*/
- if (!screen_changed_id)
- screen_changed_id = gdk_threads_add_idle (screen_changed_idle, NULL);
+ if (!screen->screen_changed_id)
+ screen->screen_changed_id = gdk_threads_add_idle (screen_changed_idle,
+ screen);
}
}
-void
-_gdk_quartz_screen_init (void)
+GdkScreen *
+_gdk_screen_quartz_new (void)
{
- gdk_screen_set_default_colormap (_gdk_screen,
- gdk_screen_get_system_colormap (_gdk_screen));
-
- screen_rects_init ();
-
- CGDisplayRegisterReconfigurationCallback (screen_changed,
- _gdk_screen);
+ return g_object_new (GDK_TYPE_SCREEN_QUARTZ, NULL);
}
GdkDisplay *
GdkColormap*
gdk_screen_get_default_colormap (GdkScreen *screen)
{
- return default_colormap;
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return GDK_SCREEN_QUARTZ (screen)->default_colormap;
}
void
g_return_if_fail (GDK_IS_SCREEN (screen));
g_return_if_fail (GDK_IS_COLORMAP (colormap));
- old_colormap = default_colormap;
+ old_colormap = GDK_SCREEN_QUARTZ (screen)->default_colormap;
- default_colormap = g_object_ref (colormap);
+ GDK_SCREEN_QUARTZ (screen)->default_colormap = g_object_ref (colormap);
if (old_colormap)
g_object_unref (old_colormap);
}
-/* FIXME: note on the get_width() and the get_height() methods. For
- * now we only support screen layouts where the screens are laid out
- * horizontally. Mac OS X also supports laying out the screens vertically
- * and the screens having "non-standard" offsets from eachother. In the
- * future we need a much more sophiscated algorithm to translate these
- * layouts to GDK coordinate space and GDK screen layout.
- */
gint
gdk_screen_get_width (GdkScreen *screen)
{
- int i;
- int width;
- NSArray *array;
-
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
- GDK_QUARTZ_ALLOC_POOL;
- array = [NSScreen screens];
-
- width = 0;
- for (i = 0; i < [array count]; i++)
- {
- NSRect rect = [[array objectAtIndex:i] frame];
- width += rect.size.width;
- }
-
- GDK_QUARTZ_RELEASE_POOL;
-
- return width;
+ return GDK_SCREEN_QUARTZ (screen)->width;
}
gint
gdk_screen_get_height (GdkScreen *screen)
{
- int i;
- int height;
- NSArray *array;
-
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
- GDK_QUARTZ_ALLOC_POOL;
- array = [NSScreen screens];
-
- height = 0;
- for (i = 0; i < [array count]; i++)
- {
- NSRect rect = [[array objectAtIndex:i] frame];
- height = MAX (height, rect.size.height);
- }
-
- GDK_QUARTZ_RELEASE_POOL;
-
- return height;
+ return GDK_SCREEN_QUARTZ (screen)->height;
}
static gint
return (pixels / dpi) * 25.4;
}
-gint
-gdk_screen_get_width_mm (GdkScreen *screen)
+static NSScreen *
+get_nsscreen_for_monitor (gint monitor_num)
{
- int i;
- gint width;
NSArray *array;
-
- g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+ NSScreen *screen;
GDK_QUARTZ_ALLOC_POOL;
- array = [NSScreen screens];
- width = 0;
- for (i = 0; i < [array count]; i++)
- {
- NSScreen *screen = [array objectAtIndex:i];
- NSRect rect = [screen frame];
- width += get_mm_from_pixels (screen, rect.size.width);
- }
+ array = [NSScreen screens];
+ screen = [array objectAtIndex:monitor_num];
GDK_QUARTZ_RELEASE_POOL;
- return width;
+ return screen;
}
gint
-gdk_screen_get_height_mm (GdkScreen *screen)
+gdk_screen_get_width_mm (GdkScreen *screen)
{
- int i;
- gint height;
- NSArray *array;
-
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
- GDK_QUARTZ_ALLOC_POOL;
- array = [NSScreen screens];
-
- height = 0;
- for (i = 0; i < [array count]; i++)
- {
- NSScreen *screen = [array objectAtIndex:i];
- NSRect rect = [screen frame];
- gint h = get_mm_from_pixels (screen, rect.size.height);
- height = MAX (height, h);
- }
-
- GDK_QUARTZ_RELEASE_POOL;
-
- return height;
+ return get_mm_from_pixels (get_nsscreen_for_monitor (0),
+ GDK_SCREEN_QUARTZ (screen)->width);
}
-int
-gdk_screen_get_n_monitors (GdkScreen *screen)
+gint
+gdk_screen_get_height_mm (GdkScreen *screen)
{
g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
- return n_screens;
+ return get_mm_from_pixels (get_nsscreen_for_monitor (0),
+ GDK_SCREEN_QUARTZ (screen)->height);
}
-static NSScreen *
-get_nsscreen_for_monitor (gint monitor_num)
+int
+gdk_screen_get_n_monitors (GdkScreen *screen)
{
- NSArray *array;
- NSScreen *screen;
-
- GDK_QUARTZ_ALLOC_POOL;
-
- array = [NSScreen screens];
- screen = [array objectAtIndex:monitor_num];
-
- GDK_QUARTZ_RELEASE_POOL;
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
- return screen;
+ return GDK_SCREEN_QUARTZ (screen)->n_screens;
}
gint
g_return_val_if_fail (monitor_num >= 0, 0);
return get_mm_from_pixels (get_nsscreen_for_monitor (monitor_num),
- screen_rects[monitor_num].width);
+ GDK_SCREEN_QUARTZ (screen)->screen_rects[monitor_num].width);
}
gint
g_return_val_if_fail (monitor_num >= 0, 0);
return get_mm_from_pixels (get_nsscreen_for_monitor (monitor_num),
- screen_rects[monitor_num].height);
+ GDK_SCREEN_QUARTZ (screen)->screen_rects[monitor_num].height);
}
gchar *
g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
g_return_if_fail (monitor_num >= 0);
- *dest = screen_rects[monitor_num];
+ *dest = GDK_SCREEN_QUARTZ (screen)->screen_rects[monitor_num];
}
gchar *